package main

import (
	"errors"
	"fmt"
	"time"

	"golang.org/x/sync/errgroup"
)

func main() {
	//testErrGroup01()
	testErrGroup02()
}

// testErrGroup01
//
//	@Description: 三个任务都执行完毕，才会返回第二个子任务的错误
func testErrGroup01() {
	var g errgroup.Group
	var now = time.Now()

	// 启动第一个子任务,它执行成功
	g.Go(func() error {
		time.Sleep(1 * time.Second)
		fmt.Println("exec #1")
		return nil
	})
	// 启动第二个子任务，它执行失败
	g.Go(func() error {
		time.Sleep(3 * time.Second)
		fmt.Println("exec #2")
		return errors.New("failed to exec #2")
	})

	// 启动第三个子任务，它执行成功
	g.Go(func() error {
		time.Sleep(5 * time.Second)
		fmt.Println("exec #3")
		return nil
	})
	// 等待三个任务都完成
	if err := g.Wait(); err == nil {
		fmt.Println(time.Since(now), "Successfully exec all")
	} else {
		fmt.Println(time.Since(now), "failed:", err)
	}
}

// testErrGroup02
//
//	@Description: 返回所有子任务的错误
func testErrGroup02() {
	var g errgroup.Group
	var now = time.Now()
	var res = make([]error, 3)

	g.Go(func() error {
		time.Sleep(1 * time.Second)
		fmt.Println("exec #1")
		res[0] = nil // 保存成功或者失败的结果
		return nil
	})
	// 启动第二个子任务，它执行失败
	g.Go(func() error {
		time.Sleep(3 * time.Second)
		fmt.Println("exec #2")
		err := errors.New("failed to exec #2")
		res[1] = err
		return err
	})

	// 启动第三个子任务，它执行成功
	g.Go(func() error {
		time.Sleep(5 * time.Second)
		fmt.Println("exec #3")
		res[2] = nil // 保存成功或者失败的结果
		return nil
	})
	// 等待三个任务都完成
	if err := g.Wait(); err == nil {
		fmt.Println(time.Since(now), "Successfully exec all")
	} else {
		fmt.Println("failed:", res)
	}
}
